package run;

/**
 * 根据JVM设计，在访问某个对象时，如果某个Class从未经过加载，那么系统会从.class文件中加载--》连接---》初始化某个对象；
 * .class文件中定义了常量池、访问标志、父索引/类索引/接口索引集合、字段表集合【接口或类中描述的变量，不含局部变量】、方法表集
 * 合【参数、访问标识、定义等】、属性表【code【方法实现时需要的代码】、异常属性、LineNumberTable集合【java源码行号和字节码行
 * 号之间的对应关系】、LocalVariableTable【栈帧中的局部变量与java源码中的局部变量之间的关系】、ConstantValue【常量】、InnerClass
 * 属性、Deprecated和Synthetic属性等】
 * 也就是说，jvm加载class后，方法区中存储有方法的入口及出口信息、实现信息等；
 * 栈帧中根据需要方法的参数来动态链接【变量转指针】；
 * 对于每个方法，都有一个默认的参数this;
 * 内部非静态类在编译之后会将外部类以参数的形式传给方法，即实现内部类拥有一个对外部类的访问指针；
 * 静态内部类编译后无外部类，可以直接使用；
 * 静态方法在加载后即可使用，无需初始化对象；
 *
 * @author wei.yang on 2018/8/11
 */
public class Child extends Parent {

    private static String CHILD = "child";

    private int a;

    static {
        System.out.println("child static:\t" + System.currentTimeMillis());
    }

    public Child() {
        System.out.println("child construct");
    }

    public static void child() {
        System.out.println(String.format("%s method.", CHILD));
    }

    public void print(int o){
        this.a=o;
    }

    /**
     * 静态内部类
     */
    static class ChildInner extends Parent.ParentInner {

        private static String CHILD_INNER = "child inner.";

        static {
            System.out.println("child inner static");
        }

        public void childInner() {
            System.out.println(String.format("%s inner method.", CHILD));
        }
    }

    /**
     * 非静态内部类
     */
    class Inner {

        /**
         * 可以调用外部类方法，但是因为非静态类的访问需要持有外部类的引用，故使用时需要先初始化外部类【详看.class文件】
         */
        void print() {
            child();
        }
    }
}
